package com.finance.logistics.computer;

import com.finance.base.enums.ComputeStatusEnum;
import com.finance.base.enums.FeeCommitStateEnum;
import com.finance.framework.lang.Page;
import com.finance.framework.lang.PageResultBO;
import com.finance.framework.lang.Privilege;
import com.finance.report.bean.pojo.LogisticsData;
import com.finance.report.bean.pojo.LogisticsExtend;
import com.finance.report.service.IComputeService;
import com.finance.report.service.ILogisticsDataService;
import com.finance.report.service.ILogisticsExtendService;
import com.finance.scheduler.SelectFilter;
import com.finance.system.bean.pojo.RecomputeTask;
import com.finance.system.bean.pojo.User;
import com.finance.system.service.IRecomputeTaskService;
import com.finance.util.DateUtil;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by CBWL on 2017/5/2.
 */
@Component
public class DataExtractor {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private ILogisticsExtendService logisticsExtendService;

    @Autowired
    private ILogisticsDataService logisticsDataService;
    @Autowired
    private IRecomputeTaskService recomputeTaskService;
    @Autowired
    private TaskExecutor taskExecutor;
    @Autowired
    private IComputeService computeService;
    @Autowired
    private SelectFilter selectFilter;

    public void extract2compute(DataExtractorParam dataExtractorParam){
        this.extract2compute(dataExtractorParam.getSignDate(),dataExtractorParam.getFeeCommited(),dataExtractorParam.getRecomputeTask(),dataExtractorParam.getPage());
    }
    private void extract2compute(Date signDate,int feeCommited,RecomputeTask recomputeTask,Page page){
        logger.info("******配费计算开始*****");
        List<LogisticsExtend> list = this.fetchWaitings(signDate, FeeCommitStateEnum.UNCOMMITTED.getState(),page);
        // list = this.selectFilter.filter(list,signDate);
        if (CollectionUtils.isNotEmpty(list)){
            for(LogisticsExtend logisticsExtend:list){
                this.dispacher(logisticsExtend,signDate);
                this.logger.info("运单{}转计算",logisticsExtend.getWaybillNum());
            }
        }
        if(recomputeTask != null && page.getPageNo() == 0 && CollectionUtils.isEmpty(list)) {
            recomputeTask.setComputeStatus(ComputeStatusEnum.OK.getState());
            User user = new User();
            user.setId(0L);
            this.recomputeTaskService.updateRecomputeTask(recomputeTask,user);
        }
        logger.info("******配费计算调用结束 异步计算中*****");
    }

    /**
     * 获取待计算运单拓展数据
     * @param signDate
     * @param feeCommited
     * @return
     */
    public List<LogisticsExtend> fetchWaitings(Date signDate,int feeCommited,Page page){
        page = page == null ? Page.getInstance(200,1) : page;
        Map param = new HashMap<>();
        param.put("dataValid", Privilege.ALL_PRIVILEGE);
        param.put("feeCommitted", feeCommited);
        page.setParams(param);
        this.logger.info("抓取拓展数据  signDate：{} feeCommited：{}",signDate,feeCommited);
        PageResultBO<LogisticsExtend> list = this.logisticsExtendService.listByPage(signDate,page);
        logger.info("****查询条件dataValid值{},结果{}",Privilege.ALL_PRIVILEGE,list);
        return list.getDataList();
    }

    private void dispacher(LogisticsExtend logisticsExtend, Date signDate){
        String tableName = logisticsDataService.getDataTableName(signDate);
        try {
            final LogisticsData logisticsData = this.logisticsDataService.getByWaybillNum(tableName,logisticsExtend.getWaybillNum());
            this.taskExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    DataExtractor.this.computeEntrance(logisticsData);
                }
            });
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    public void computeEntrance(LogisticsData logisticsData){
        this.logger.info("计算开始：{} 运单号：{}", DateUtil.dateFormat(new Date(),"yyyy-MM-dd HH:mm:ss"), logisticsData.getWaybillNum());
        LogisticsExtend logisticsExtend = this.logisticsExtendService.getByWayBillNum(logisticsData.getSignTime(),logisticsData.getWaybillNum());
        if(logisticsExtend == null|| logisticsExtend.getFeeCommitted() == FeeCommitStateEnum.COMMITTED.getState()){
            this.logger.info("{}此单数据异常或已计算,跳过",logisticsData.getWaybillNum());
            return;
        }
        this.computeService.handleCompute(logisticsData,logisticsExtend);
        this.logger.info("计算结束：{} 运单号：{}", DateUtil.dateFormat(new Date(),"yyyy-MM-dd HH:mm:ss"), logisticsData.getWaybillNum());
    }
}
